﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Net;

namespace IndustrialMusicWindowsCSharp {
    public partial class ParseIndustrialSample : Form {
        public ParseIndustrialSample() {
            InitializeComponent();
            BindSourceTypes();
            BindSources();
        }

        private void BindSources() {
            comboSourceType.DataSource = DataLayer.ParseIndustrialSamplesDao.GetSampleSourceTypes();
            comboSourceType.DisplayMember = "sourcetype_text";
        }

        private void BindSourceTypes() {
            comboSources.DataSource = DataLayer.ParseIndustrialSamplesDao.GetSampleSources();
            comboSources.DisplayMember = "source_text";
        }

        private void btnCancel_Click(object sender, EventArgs e) {
            this.Close();
        }

        private void btnFormat_Click(object sender, EventArgs e) {
            Regex returns = new Regex(@"\r\n");
            txtSampleText.Text = returns.Replace(txtSampleText.Text, String.Empty);
        }

        private void btnParse_Click(object sender, EventArgs e) {
            Regex parseSongBandRelease = new Regex(@"\s*?-*\s*?(.*?);\s*?(.*?);\s*?(.*)");
            MatchCollection songBandReleaseMatches = parseSongBandRelease.Matches(txtSongBandRelease.Text);

            if (songBandReleaseMatches.Count > 0) {
                txtSong.Text = songBandReleaseMatches[0].Groups[2].Value.Trim();
                txtBand.Text = songBandReleaseMatches[0].Groups[1].Value.Trim();
                txtRelease.Text = songBandReleaseMatches[0].Groups[3].Value.Trim();
            }
       }

        private void btnClearAll_Click(object sender, EventArgs e) {
            txtBand.Text = string.Empty;
            txtRelease.Text = string.Empty;
            txtSampleText.Text = string.Empty;
            txtSong.Text = string.Empty;
            txtSongBandRelease.Text = string.Empty;
            comboSourceType.Text = string.Empty;
            comboSources.Text = string.Empty;
        }

        private void btnSave_Click(object sender, EventArgs e) {
            XElement artists = XElement.Load("Samples.xml");

            XElement artist = null;
            XElement release = null;
            XElement song = null;
            XElement sample = null;

            song = GetSong(artists, txtBand.Text.Trim(), txtRelease.Text.Trim(), txtSong.Text.Trim());

            if (song != null) {
                sample = CreateSampleNode(txtSampleText.Text.Trim(), comboSources.Text, comboSourceType.Text, txtTimeLocation.Text.Trim());
                song.Add(sample);
            } else {
                artist = GetArtist(artists, txtBand.Text.Trim());

                if ( artist != null ){
                    release = GetRelease(artist, txtRelease.Text.Trim());

                    if (release == null ){
                        release = CreateReleaseNode(txtRelease.Text.Trim());
                        artist.Add(release);
                    }

                    song = CreateSongNode(txtSong.Text.Trim());
                    sample = CreateSampleNode(txtSampleText.Text, comboSources.Text, comboSourceType.Text, txtTimeLocation.Text.Trim());

                    song.Add(sample);
                    release.Add(song);
                } else {
                    artist = CreateArtistNode(txtBand.Text.Trim());
                    release = CreateReleaseNode(txtRelease.Text.Trim());
                    song = CreateSongNode(txtSong.Text.Trim());
                    sample = CreateSampleNode(txtSampleText.Text, comboSources.Text, comboSourceType.Text, txtTimeLocation.Text.Trim());

                    song.Add(sample);
                    release.Add(song);
                    artist.Add(release);
                    artists.Add(artist);
                }
            }

            artists.Save("Samples.xml");
            MessageBox.Show("Sample saved!");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sampleText"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        private XElement CreateSampleNode(string sampleText, string sourceText, string sourceType, string sourceTimeLocation) {
            XElement sampleElement = new XElement("sample");
            XElement textElement = new XElement("text",sampleText);
            XElement sourceElement = new XElement("source", sourceText);
            XAttribute sampleTimeLocationAttribute = new XAttribute("timelocation", sourceTimeLocation);
            XAttribute sourceTypeAttribute = new XAttribute("sourcetype", sourceType);
            
            sourceElement.Add(sourceTypeAttribute);
            sampleElement.Add(sampleTimeLocationAttribute);
            sampleElement.Add(textElement);
            sampleElement.Add(sourceElement);

            return sampleElement;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="songName"></param>
        /// <returns></returns>
        private XElement CreateSongNode(string songName) {
            XElement songElement = new XElement("song");
            XAttribute nameAttribute = new XAttribute("name", songName);

            songElement.Add(nameAttribute);

            return songElement;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="releaseName"></param>
        /// <returns></returns>
        private XElement CreateReleaseNode(string releaseName) {
            XElement releaseElement = new XElement("release");
            XAttribute nameAttribute = new XAttribute("name", releaseName);

            releaseElement.Add(nameAttribute);

            return releaseElement;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artistName"></param>
        /// <returns></returns>
        private XElement CreateArtistNode(string artistName) {
            XElement artistElement = new XElement("artist");
            XAttribute nameAttribute = new XAttribute("name", artistName);

            artistElement.Add(nameAttribute);

            return artistElement;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artists"></param>
        /// <param name="artistName"></param>
        /// <returns></returns>
        private XElement GetArtist(XElement artists, string artistName) {
            XElement artistResult = null;

            var query = from artist in artists.Descendants("artist")
                        where artist.Attribute("name") != null &&
                            artist.Attribute("name").Value == artistName
                        select artist;

            if (query.Count<XElement>() == 1) {
                artistResult = query.First<XElement>();
            }

            return artistResult;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artists"></param>
        /// <param name="artistName"></param>
        /// <param name="releaseName"></param>
        /// <returns></returns>
        private XElement GetRelease(XElement artists, string artistName, string releaseName) {
            XElement releaseResult = null;

            var query = from artist in artists.Descendants("artist")
                        where artist.Attribute("name") != null &&
                            artist.Attribute("name").Value == artistName
                        from release in artist.Descendants("release")
                        where release.Attribute("name") != null &&
                            release.Attribute("name").Value == releaseName
                        select release;

            if (query.Count<XElement>() == 1) {
                releaseResult = query.First<XElement>();
            }

            return releaseResult;
        }

        private XElement GetRelease(XElement artist, string releaseName) {
            XElement releaseResult = null;

            var query = from release in artist.Descendants("release")
                        where release.Attribute("name") != null &&
                            release.Attribute("name").Value == releaseName
                        select release;

            if (query.Count<XElement>() == 1) {
                releaseResult = query.First<XElement>();
            }

            return releaseResult;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="artists"></param>
        /// <param name="artistName"></param>
        /// <param name="releaseName"></param>
        /// <param name="songName"></param>
        /// <returns></returns>
        private XElement GetSong(XElement artists, string artistName, string releaseName, string songName) {
            XElement songResult = null;

            var query = from artist in artists.Descendants("artist")
                        where artist.Attribute("name") != null &&
                            artist.Attribute("name").Value == artistName
                        from release in artist.Descendants("release")
                        where release.Attribute("name") != null &&
                            release.Attribute("name").Value == releaseName
                        from song in release.Descendants("song")
                        where song.Attribute("name") != null &&
                            song.Attribute("name").Value == songName
                        select song;

            if (query.Count<XElement>() == 1) {
                songResult = query.First<XElement>();
            }

            return songResult;
        }

        private void btnClearSample_Click(object sender, EventArgs e) {
            txtSampleText.Text = string.Empty;
            txtTimeLocation.Text = string.Empty;
        }

        private void btnClearArtistInfo_Click(object sender, EventArgs e) {
            txtSongBandRelease.Text = string.Empty;
            txtSong.Text = string.Empty;
            txtBand.Text = string.Empty;
            txtRelease.Text = string.Empty;
        }
    }
}
